package com.cxs.tetrisdemo.tetris;

import com.cxs.tetrisdemo.util.Utils;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.app.Context;

import java.util.ArrayList;

import static com.cxs.tetrisdemo.common.Constant.GRID_COLS;
import static com.cxs.tetrisdemo.common.Constant.GRID_ROWS;

/*
    画俄罗斯方块
 */
public class TetrisBlock extends TetrisGrid {

    private Paint paint;
    boolean blocked = false;    // 遇到障碍

    public BlockStyle nextBlock;
    public BlockStyle block;

    int len;
    // 方块种类， 4 * 7
    int styles[][] = {
            { 0x0f00, 0x4444, 0x0f00, 0x4444 },     // 长条
            { 0x6600, 0x6600, 0x6600, 0x6600 },     // 正方
            { 0x4E00, 0X4640, 0x7200, 0x4C40 },     // 丁字
            { 0xC600, 0x4C80, 0xC600, 0x4C80 },     // 正Z
            { 0x6C00, 0x8C40, 0x6C00, 0x8C40 },     // 反Z
            { 0x4460, 0x0E80, 0xC440, 0x2E00 },     // L
            { 0x44C0, 0x8E00, 0x6440, 0x0E20 }      // 反L
    };

    public TetrisBlock(Context context, int len) {
        super(context, len);
        this.len = len;
        initPaint();
    }
    /*
        初始化画笔
     */
    private void initPaint() {
        paint = new Paint();
        paint.setColor(Color.GREEN);
    }

    /*
        开始画俄罗斯方块
     */
    public void drawTetrisGrids(Canvas canvas) {
        // 画网格
        drawGrid(canvas);
        // 画方块
        for (int col = 0; col < GRID_COLS; col++) {
            for (int row = 0; row < GRID_ROWS; row++) {
                if (grids[col + 3][row] == '1') {
                    canvas.drawRect(col * len + 4, row * len + 4, (col+1) * len - 8, (row+1) * len - 8, paint);
                }
            }
        }
    }

    /**
     * 更新网格的二进制值
     * @param pos   方块位置
     * @param block 方块
     * @return
     */
    protected boolean setGrids(Position pos, BlockStyle block) {
        // 获取方块的16进制值并转换为二进制字符串
        String str = Integer.toBinaryString(block.getBlock());
        // 获取俄罗斯方块的状态
        char[][] blocks = Utils.getArray(str);

        copyGrids(preGrids, tmpGrids);    // 重置临时网格
        blocked = false;    // 重置受阻状态

        a: for (int x = 0; x < 4; x++) {
            for (int y = 0; y < 4; y++) {
                try {
                    if (tmpGrids[pos.X + 3 + x][pos.Y + y] == '1'
                            && blocks[x][y] == '1') {
                        // 受阻
                        copyGrids(preGrids, tmpGrids);
                        blocked = true;
                        break a;
                    } else {
                        // 判断 如果行>=20，或方块的block为0则不赋值
                        if (pos.Y + y < GRID_ROWS && blocks[x][y] != '0') {
                            tmpGrids[pos.X + 3 + x][pos.Y + y] = blocks[x][y];
                        }
                    }
                }catch (ArrayIndexOutOfBoundsException e) {
                    e.printStackTrace();
                }

            }
        }

        if (!blocked) {
            // 如果没有受阻，则可以移动，更新当前网格状态为移动后的状态
            copyGrids(tmpGrids, grids);
        }
        return blocked;
    }

    /*
        检查可消除的行
     */
    protected void checkEliminate() {
        int blockedSum = 0;    //
        ArrayList<Integer> list = new ArrayList<>();

        // 从底部开始向上遍历
        b:for (int y = GRID_ROWS - 1; y <= 0; y--) {
            for (int x = 3; x < GRID_COLS + 3; x++) {
                if (grids[x][y] == '1') {
                    // 如果该block被填充
                    blockedSum++;
                } else {
                    // 跳出这一行的循环，继续循环下一行
                    break;
                }
            }
            if (blockedSum == 0) {
                // 如果该行全是空，则跳出外循环
                break b;
            } else if (blockedSum == 10) {
                // 如果该行全被block填满了，则向集合中添加该行的行号
                list.add(y);
            }
            blockedSum = 0;
        }

        if (list.size() > 0) {
            // 如果可消除的行大于0

        }
    }

    public class BlockStyle {
        int style;    // 方块种类
        int angle;     // 方块旋转角度

        public BlockStyle(int style, int angle) {
            this.style = style;
            this.angle = angle;
        }

        public int getBlock() {
            return styles[style][angle];
        }

        public void rorate() {
            this.angle++;
            if (this.angle >= 4) {
                this.angle = 0;
            }
        }

        public int getStyle() {
            return style;
        }

        public void setStyle(int style) {
            this.style = style;
        }


    }

}
